import chalk from "chalk";
import type { Chalk } from "chalk";
import type { PrintOpts } from "./index.d";

export class Print {
  static readonly Log = console.log;

  private static _base(
    pen: Chalk, msg: string,
    {
      prefix = "",
      suffix = "",
      around = false,
    }: PrintOpts = {}) {
    let _template = `%s${msg}%s`;
    around && (_template = ` ${_template} `);

    this.Log(pen(_template), prefix, suffix);
  }

  static info(
    msg: string,
    opts: PrintOpts = {}
  ) {
    let pen = chalk.bgWhite.black;
    const { inverse, around = true, prefix = "INFO: " } = opts;

    inverse && (pen = pen.inverse);
    this._base(pen, msg, { ...opts, around, prefix });
  }

  static success(
    msg: string,
    opts: PrintOpts = {}
  ) {
    let pen = chalk.bgGreen.black;
    const { inverse, around = true, prefix = "SUCCESS: " } = opts;

    inverse && (pen = pen.inverse);
    this._base(pen, msg, { ...opts, around, prefix });
  }

  static error(
    msg: Error | string,
    opts: PrintOpts = {}
  ) {
    let pen = chalk.bgRed.black;
    const { inverse, around = true, prefix = "ERROR: " } = opts;

    if (msg instanceof Error) {
      msg = msg.toString();
    }
    inverse && (pen = pen.inverse);
    this._base(pen, msg, { ...opts, around, prefix });
  }

  static println(msg: string, ...args: string[]) {
    let pen = chalk;
    for (const i of args) {
      pen = pen[i];
    }
    this.Log(pen(msg));
  }
}
